package com.lcz.licence.config;

import com.lcz.licence.entity.LicenseVerifyParam;
import com.lcz.licence.util.LicenseVerify;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @author lcz
 * @desc 许可证检查监听器，用于在应用程序上下文刷新时进行许可证的安装。
 * 实现了ApplicationListener接口，用于监听ContextRefreshedEvent事件。
 * @mail lcz_0130@163.com
 * @date 2025/07/23
 */
@Slf4j
@Component
public class LicenseCheckListener implements ApplicationListener<ContextRefreshedEvent> {

    private static final String CLASSPATH_RESOURCE_PREFIX = "classpath:";

    /**
     * 许可证的主题
     */
    @Value("${license.subject}")
    private String subject;

    /**
     * 公钥的别名
     */
    @Value("${license.publicAlias}")
    private String publicAlias;

    /**
     * 访问公钥库的密码
     */
    @Value("${license.storePass}")
    private String storePass;

    /**
     * 证书的生成路径
     */
    @Value("${license.licensePath}")
    private String licensePath;

    /**
     * 当上下文被刷新时触发此方法。检查是否为根应用上下文，是则安装证书。
     *
     * @param event 上下文刷新事件
     */
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        // 检查是否是根应用上下文，避免在子上下文中重复安装证书
        ApplicationContext context = event.getApplicationContext().getParent();
        if (context == null) {
            if (StringUtils.isNotBlank(licensePath)) {
                log.info("++++++++ 开始安装证书 ++++++++");
                LicenseVerifyParam param = new LicenseVerifyParam();
                if (licensePath.startsWith(CLASSPATH_RESOURCE_PREFIX)) {
                    try {
                        licensePath = new ClassPathResource(licensePath.replaceAll(CLASSPATH_RESOURCE_PREFIX, ""))
                                .getFile().getAbsolutePath();
                    } catch (IOException e) {
                        throw new RuntimeException("证书文件不存在");
                    }
                }

                param.setSubject(subject);
                param.setPublicAlias(publicAlias);
                param.setStorePass(storePass);
                param.setLicensePath(licensePath + "/license.lic");
                param.setPublicKeysStorePath(licensePath + "/publicCerts.keystore");
                LicenseVerify licenseVerify = new LicenseVerify();
                licenseVerify.install(param);
                log.info("++++++++ 证书安装结束 ++++++++");
            }
        }
    }
}
